package robocup.component.worldobjects;

import robocup.component.geometry.Vektor;

/**
 * StaticObject is the representation of anything on the soccerfield, that has a
 * position. It therefore is extended by the classes Flag and DynamicObject.
 */
public abstract class StaticObject {

  /**
   * The cycle, in which it was seen.
   */
  private int      cycle     = -1;

  /**
   * The bodyCycle, in which it was seen (this is incremented always, not only
   * if a new gameCycle arrives)
   */
  private int      bodyCycle = -1;

  /**
   * The position of the StaticObject.
   */
  protected final Vektor position  = new Vektor();

  /**
   * Creates a new <code>StaticObject</code>, an object that has a position,
   * but not a speed.
   * 
   * @param iCycle -
   *          time, when the object was seen last (real cycle)
   * @param bodyCycle -
   *          time, when the object was seen last (body cycle)
   * @param iPosAbs -
   *          the absolute position of the object
   */
  public StaticObject(
      final int iCycle,
      final int bodyCycle,
      final Vektor iPosAbs) {

    this.cycle = iCycle;
    this.position.x = iPosAbs.x;
    this.position.y = iPosAbs.y;
    this.bodyCycle = bodyCycle;
  }

  /**
   * @return Returns the cycle.
   */
  public int getCycle() {

    return this.cycle;
  }

  /**
   * <code>getPosition</code>
   * 
   * @return Returns the object's position. Note that if you perform operations
   *         on this Vektor that change it, you need to clone it first!
   */
  public final Vektor getPosition() {

    return this.position;
  }

  /**
   * distance to an object
   * 
   * @param o -
   *          StaticObject
   * @return distance to the object
   */
  public final double getDistance(final StaticObject o) {

    return this.getPosition().getDistance(o.getPosition());
  }

  /**
   * distance to a point (Vektor)
   * 
   * @param v -
   *          point
   * @return distance to the object
   */
  public final double getDistance(final Vektor v) {

    return this.getPosition().getDistance(v);
  }

  /**
   * @param o -
   *          StaticObject with global position
   * @return Vektor - from the position of this StaticObject to the position of
   *         the specified StaticObject <code>o</code>.
   */
  public final Vektor getVektorTo(final StaticObject o) {

    return this.getVektorTo(o.getPosition());
  }

  /**
   * @param absolutePosition -
   *          global Vektor
   * @return Vektor - from this Vektor to the specified global Vektor
   *         <code>absolutePosition</code>
   */
  public final Vektor getVektorTo(final Vektor absolutePosition) {

    return this.getPosition().getVektorTo(absolutePosition);
  }


  /**
   * Returns a Vektor from this Vektor to the global Vektor <code>v</code>.
   * Note that this method is equal to <code>v</code>.sub(<code>this</code>).
   * 
   * @param absolutePosition -
   *          global Vektor
   * @param result -
   *          here the result is saved (overwrites old contents)
   */
  public final void getVektorTo(final Vektor absolutePosition, final Vektor result) {
    this.getPosition().getVektorTo(absolutePosition, result);
  }

  /**
   * @param o -
   *          StaticObject with global position
   * @return double - angle from the position of this StaticObject to the global
   *         position of the specified StaticObject <code>o</code>
   */
  public final double getAngleTo(final StaticObject o) {

    return this.getAngleTo(o.getPosition());
  }

  /**
   * @param absolutePosition -
   *          global Vektor
   * @return double - angle from the position of this StaticObject to the global
   *         Vektor <code>absolutePosition</code>.
   */
  public final double getAngleTo(final Vektor absolutePosition) {

    return this.getPosition().getAngleTo(absolutePosition);
  }

  /**
   * @param cycle
   *          The cycle to set.
   */
  public void setCycle(final int cycle) {

    this.cycle = cycle;
  }

  /**
   * @param position
   *          The position to set.
   */
  public void setPosition(final Vektor position) {

    this.position.x = position.x;
    this.position.y = position.y;
  }

  /**
   * @return Returns the bodyCycle.
   */
  public int getBodyCycle() {

    return this.bodyCycle;
  }

  /**
   * @param bodyCycle
   *          The bodyCycle to set.
   */
  public void setBodyCycle(final int bodyCycle) {

    this.bodyCycle = bodyCycle;
  }
}
